gdkcursor-win32.c \
gdkdevicemanager-win32.c \
gdkdevicemanager-win32.h \
+ gdkdevice-virtual.c \
+ gdkdevice-virtual.h \
gdkdevice-win32.c \
gdkdevice-win32.h \
gdkdevice-wintab.c \
--- /dev/null
+/* GDK - The GIMP Drawing Kit\r
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#include "config.h"\r
+\r
+#include <gdk/gdkwindow.h>\r
+\r
+#include <windowsx.h>\r
+#include <objbase.h>\r
+\r
+#include "gdkdisplayprivate.h"\r
+#include "gdkdevice-virtual.h"\r
+#include "gdkwin32.h"\r
+\r
+static gboolean gdk_device_virtual_get_history (GdkDevice *device,\r
+ GdkWindow *window,\r
+ guint32 start,\r
+ guint32 stop,\r
+ GdkTimeCoord ***events,\r
+ gint *n_events);\r
+static void gdk_device_virtual_get_state (GdkDevice *device,\r
+ GdkWindow *window,\r
+ gdouble *axes,\r
+ GdkModifierType *mask);\r
+static void gdk_device_virtual_set_window_cursor (GdkDevice *device,\r
+ GdkWindow *window,\r
+ GdkCursor *cursor);\r
+static void gdk_device_virtual_warp (GdkDevice *device,\r
+ GdkScreen *screen,\r
+ gint x,\r
+ gint y);\r
+static void gdk_device_virtual_query_state (GdkDevice *device,\r
+ GdkWindow *window,\r
+ GdkWindow **root_window,\r
+ GdkWindow **child_window,\r
+ gint *root_x,\r
+ gint *root_y,\r
+ gint *win_x,\r
+ gint *win_y,\r
+ GdkModifierType *mask);\r
+static GdkGrabStatus gdk_device_virtual_grab (GdkDevice *device,\r
+ GdkWindow *window,\r
+ gboolean owner_events,\r
+ GdkEventMask event_mask,\r
+ GdkWindow *confine_to,\r
+ GdkCursor *cursor,\r
+ guint32 time_);\r
+static void gdk_device_virtual_ungrab (GdkDevice *device,\r
+ guint32 time_);\r
+static GdkWindow * gdk_device_virtual_window_at_position (GdkDevice *device,\r
+ gint *win_x,\r
+ gint *win_y,\r
+ GdkModifierType *mask,\r
+ gboolean get_toplevel);\r
+static void gdk_device_virtual_select_window_events (GdkDevice *device,\r
+ GdkWindow *window,\r
+ GdkEventMask event_mask);\r
+\r
+\r
+G_DEFINE_TYPE (GdkDeviceVirtual, gdk_device_virtual, GDK_TYPE_DEVICE)\r
+\r
+static void\r
+gdk_device_virtual_class_init (GdkDeviceVirtualClass *klass)\r
+{\r
+ GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);\r
+\r
+ device_class->get_history = gdk_device_virtual_get_history;\r
+ device_class->get_state = gdk_device_virtual_get_state;\r
+ device_class->set_window_cursor = gdk_device_virtual_set_window_cursor;\r
+ device_class->warp = gdk_device_virtual_warp;\r
+ device_class->query_state = gdk_device_virtual_query_state;\r
+ device_class->grab = gdk_device_virtual_grab;\r
+ device_class->ungrab = gdk_device_virtual_ungrab;\r
+ device_class->window_at_position = gdk_device_virtual_window_at_position;\r
+ device_class->select_window_events = gdk_device_virtual_select_window_events;\r
+}\r
+\r
+static void\r
+gdk_device_virtual_init (GdkDeviceVirtual *device_virtual)\r
+{\r
+ GdkDevice *device;\r
+\r
+ device = GDK_DEVICE (device_virtual);\r
+\r
+}\r
+\r
+void\r
+_gdk_device_virtual_set_active (GdkDevice *device,\r
+ GdkDevice *new_active)\r
+{\r
+ GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);\r
+ int n_axes, i;\r
+ GdkAtom label_atom;\r
+ GdkAxisUse use;\r
+ gdouble min_value, max_value, resolution;\r
+\r
+ if (virtual->active_device == new_active)\r
+ return;\r
+\r
+ virtual->active_device = new_active;\r
+ \r
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)\r
+ {\r
+ _gdk_device_reset_axes (device);\r
+ n_axes = gdk_device_get_n_axes (new_active);\r
+ for (i = 0; i < n_axes; i++)\r
+ {\r
+ _gdk_device_get_axis_info (new_active, i,\r
+ &label_atom, &use, \r
+ &min_value, &max_value, &resolution);\r
+ _gdk_device_add_axis (device,\r
+ label_atom, use, \r
+ min_value, max_value, resolution);\r
+ }\r
+ }\r
+\r
+ g_signal_emit_by_name (G_OBJECT (device), "changed");\r
+}\r
+\r
+static gboolean\r
+gdk_device_virtual_get_history (GdkDevice *device,\r
+ GdkWindow *window,\r
+ guint32 start,\r
+ guint32 stop,\r
+ GdkTimeCoord ***events,\r
+ gint *n_events)\r
+{\r
+ /* History is only per slave device */\r
+ return FALSE;\r
+}\r
+\r
+static void\r
+gdk_device_virtual_get_state (GdkDevice *device,\r
+ GdkWindow *window,\r
+ gdouble *axes,\r
+ GdkModifierType *mask)\r
+{\r
+ GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);\r
+ GdkDevice *active = virtual->active_device;\r
+\r
+ GDK_DEVICE_GET_CLASS (active)->get_state (active,\r
+ window, axes, mask);\r
+}\r
+\r
+static void\r
+gdk_device_virtual_set_window_cursor (GdkDevice *device,\r
+ GdkWindow *window,\r
+ GdkCursor *cursor)\r
+{\r
+ GdkWin32Cursor *cursor_private;\r
+ GdkWindow *parent_window;\r
+ GdkWindowImplWin32 *impl;\r
+ HCURSOR hcursor;\r
+ HCURSOR hprevcursor;\r
+\r
+ impl = GDK_WINDOW_IMPL_WIN32 (window->impl);\r
+ cursor_private = (GdkWin32Cursor*) cursor;\r
+\r
+ hprevcursor = impl->hcursor;\r
+\r
+ if (!cursor)\r
+ hcursor = NULL;\r
+ else\r
+ hcursor = cursor_private->hcursor;\r
+\r
+ if (hcursor != NULL)\r
+ {\r
+ /* If the pointer is over our window, set new cursor */\r
+ GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);\r
+\r
+ if (curr_window == window ||\r
+ (curr_window && window == gdk_window_get_toplevel (curr_window)))\r
+ SetCursor (hcursor);\r
+ else\r
+ {\r
+ /* Climb up the tree and find whether our window is the\r
+ * first ancestor that has cursor defined, and if so, set\r
+ * new cursor.\r
+ */\r
+ while (curr_window && curr_window->impl &&\r
+ !GDK_WINDOW_IMPL_WIN32 (curr_window->impl)->hcursor)\r
+ {\r
+ curr_window = curr_window->parent;\r
+ if (curr_window == GDK_WINDOW (window))\r
+ {\r
+ SetCursor (hcursor);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Unset the previous cursor: Need to make sure it's no longer in\r
+ * use before we destroy it, in case we're not over our window but\r
+ * the cursor is still set to our old one.\r
+ */\r
+ if (hprevcursor != NULL &&\r
+ GetCursor () == hprevcursor)\r
+ {\r
+ /* Look for a suitable cursor to use instead */\r
+ hcursor = NULL;\r
+ parent_window = GDK_WINDOW (window)->parent;\r
+\r
+ while (hcursor == NULL)\r
+ {\r
+ if (parent_window)\r
+ {\r
+ impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);\r
+ hcursor = impl->hcursor;\r
+ parent_window = parent_window->parent;\r
+ }\r
+ else\r
+ hcursor = LoadCursor (NULL, IDC_ARROW);\r
+ }\r
+\r
+ SetCursor (hcursor);\r
+ }\r
+}\r
+\r
+static void\r
+gdk_device_virtual_warp (GdkDevice *device,\r
+ GdkScreen *screen,\r
+ gint x,\r
+ gint y)\r
+{\r
+ SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);\r
+}\r
+\r
+static void\r
+gdk_device_virtual_query_state (GdkDevice *device,\r
+ GdkWindow *window,\r
+ GdkWindow **root_window,\r
+ GdkWindow **child_window,\r
+ gint *root_x,\r
+ gint *root_y,\r
+ gint *win_x,\r
+ gint *win_y,\r
+ GdkModifierType *mask)\r
+{\r
+ GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);\r
+\r
+ _gdk_device_query_state (virtual->active_device,\r
+ window, root_window, child_window,\r
+ root_x, root_y,\r
+ win_x, win_y,\r
+ mask);\r
+}\r
+\r
+static GdkGrabStatus\r
+gdk_device_virtual_grab (GdkDevice *device,\r
+ GdkWindow *window,\r
+ gboolean owner_events,\r
+ GdkEventMask event_mask,\r
+ GdkWindow *confine_to,\r
+ GdkCursor *cursor,\r
+ guint32 time_)\r
+{\r
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);\r
+ HCURSOR hcursor;\r
+ GdkWin32Cursor *cursor_private;\r
+\r
+ cursor_private = (GdkWin32Cursor*) cursor;\r
+\r
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)\r
+ {\r
+ if (!cursor)\r
+ hcursor = NULL;\r
+ else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)\r
+ WIN32_API_FAILED ("CopyCursor");\r
+\r
+ if (_gdk_win32_grab_cursor != NULL)\r
+ {\r
+ if (GetCursor () == _gdk_win32_grab_cursor)\r
+ SetCursor (NULL);\r
+ DestroyCursor (_gdk_win32_grab_cursor);\r
+ }\r
+\r
+ _gdk_win32_grab_cursor = hcursor;\r
+\r
+ if (_gdk_win32_grab_cursor != NULL)\r
+ SetCursor (_gdk_win32_grab_cursor);\r
+ else if (impl->hcursor != NULL)\r
+ SetCursor (impl->hcursor);\r
+ else\r
+ SetCursor (LoadCursor (NULL, IDC_ARROW));\r
+\r
+ SetCapture (GDK_WINDOW_HWND (window));\r
+ }\r
+\r
+ return GDK_GRAB_SUCCESS;\r
+}\r
+\r
+static void\r
+gdk_device_virtual_ungrab (GdkDevice *device,\r
+ guint32 time_)\r
+{\r
+ GdkDeviceGrabInfo *info;\r
+ GdkDisplay *display;\r
+\r
+ display = gdk_device_get_display (device);\r
+ info = _gdk_display_get_last_device_grab (display, device);\r
+\r
+ if (info)\r
+ info->serial_end = 0;\r
+\r
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)\r
+ {\r
+ if (_gdk_win32_grab_cursor != NULL)\r
+ {\r
+ if (GetCursor () == _gdk_win32_grab_cursor)\r
+ SetCursor (NULL);\r
+ DestroyCursor (_gdk_win32_grab_cursor);\r
+ }\r
+ _gdk_win32_grab_cursor = NULL;\r
+\r
+ ReleaseCapture ();\r
+ }\r
+\r
+ _gdk_display_device_grab_update (display, device, NULL, 0);\r
+}\r
+\r
+static void\r
+screen_to_client (HWND hwnd, POINT screen_pt, POINT *client_pt)\r
+{\r
+ *client_pt = screen_pt;\r
+ ScreenToClient (hwnd, client_pt);\r
+}\r
+\r
+static GdkWindow *\r
+gdk_device_virtual_window_at_position (GdkDevice *device,\r
+ gint *win_x,\r
+ gint *win_y,\r
+ GdkModifierType *mask,\r
+ gboolean get_toplevel)\r
+{\r
+ GdkWindow *window = NULL;\r
+ POINT screen_pt, client_pt;\r
+ HWND hwnd, hwndc;\r
+ RECT rect;\r
+\r
+ GetCursorPos (&screen_pt);\r
+\r
+ if (get_toplevel)\r
+ {\r
+ /* Only consider visible children of the desktop to avoid the various\r
+ * non-visible windows you often find on a running Windows box. These\r
+ * might overlap our windows and cause our walk to fail. As we assume\r
+ * WindowFromPoint() can find our windows, we follow similar logic\r
+ * here, and ignore invisible and disabled windows.\r
+ */\r
+ hwnd = GetDesktopWindow ();\r
+ do {\r
+ window = gdk_win32_handle_table_lookup (hwnd);\r
+\r
+ if (window != NULL &&\r
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT &&\r
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)\r
+ break;\r
+\r
+ screen_to_client (hwnd, screen_pt, &client_pt);\r
+ hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED |\r
+ CWP_SKIPINVISIBLE);\r
+\r
+ /* Verify that we're really inside the client area of the window */\r
+ if (hwndc != hwnd)\r
+ {\r
+ GetClientRect (hwndc, &rect);\r
+ screen_to_client (hwndc, screen_pt, &client_pt);\r
+ if (!PtInRect (&rect, client_pt))\r
+ hwndc = hwnd;\r
+ }\r
+\r
+ } while (hwndc != hwnd && (hwnd = hwndc, 1));\r
+\r
+ }\r
+ else\r
+ {\r
+ hwnd = WindowFromPoint (screen_pt);\r
+\r
+ /* Verify that we're really inside the client area of the window */\r
+ GetClientRect (hwnd, &rect);\r
+ screen_to_client (hwnd, screen_pt, &client_pt);\r
+ if (!PtInRect (&rect, client_pt))\r
+ hwnd = NULL;\r
+\r
+ /* If we didn't hit any window at that point, return the desktop */\r
+ if (hwnd == NULL)\r
+ {\r
+ if (win_x)\r
+ *win_x = screen_pt.x + _gdk_offset_x;\r
+ if (win_y)\r
+ *win_y = screen_pt.y + _gdk_offset_y;\r
+ return _gdk_root;\r
+ }\r
+\r
+ window = gdk_win32_handle_table_lookup (hwnd);\r
+ }\r
+\r
+ if (window && (win_x || win_y))\r
+ {\r
+ if (win_x)\r
+ *win_x = client_pt.x;\r
+ if (win_y)\r
+ *win_y = client_pt.y;\r
+ }\r
+\r
+ return window;\r
+}\r
+\r
+static void\r
+gdk_device_virtual_select_window_events (GdkDevice *device,\r
+ GdkWindow *window,\r
+ GdkEventMask event_mask)\r
+{\r
+}\r
--- /dev/null
+/* GDK - The GIMP Drawing Kit\r
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#ifndef __GDK_DEVICE_VIRTUAL_H__\r
+#define __GDK_DEVICE_VIRTUAL_H__\r
+\r
+#include <gdk/gdkdeviceprivate.h>\r
+\r
+G_BEGIN_DECLS\r
+\r
+#define GDK_TYPE_DEVICE_VIRTUAL (gdk_device_virtual_get_type ())\r
+#define GDK_DEVICE_VIRTUAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_VIRTUAL, GdkDeviceVirtual))\r
+#define GDK_DEVICE_VIRTUAL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_VIRTUAL, GdkDeviceVirtualClass))\r
+#define GDK_IS_DEVICE_VIRTUAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_VIRTUAL))\r
+#define GDK_IS_DEVICE_VIRTUAL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_VIRTUAL))\r
+#define GDK_DEVICE_VIRTUAL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_VIRTUAL, GdkDeviceVirtualClass))\r
+\r
+typedef struct _GdkDeviceVirtual GdkDeviceVirtual;\r
+typedef struct _GdkDeviceVirtualClass GdkDeviceVirtualClass;\r
+\r
+struct _GdkDeviceVirtual\r
+{\r
+ GdkDevice parent_instance;\r
+ GdkDevice *active_device;\r
+};\r
+\r
+struct _GdkDeviceVirtualClass\r
+{\r
+ GdkDeviceClass parent_class;\r
+};\r
+\r
+GType gdk_device_virtual_get_type (void) G_GNUC_CONST;\r
+\r
+void _gdk_device_virtual_set_active (GdkDevice *device,\r
+ GdkDevice *new_active);\r
+\r
+\r
+G_END_DECLS\r
+\r
+#endif /* __GDK_DEVICE_VIRTUAL_H__ */\r
GdkWindow *window,
GdkCursor *cursor)
{
- GdkWin32Cursor *cursor_private;
- GdkWindow *parent_window;
- GdkWindowImplWin32 *impl;
- HCURSOR hcursor;
- HCURSOR hprevcursor;
-
- impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- cursor_private = (GdkWin32Cursor*) cursor;
-
- hprevcursor = impl->hcursor;
-
- if (!cursor)
- hcursor = NULL;
- else
- hcursor = cursor_private->hcursor;
-
- if (hcursor != NULL)
- {
- /* If the pointer is over our window, set new cursor */
- GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
-
- if (curr_window == window ||
- (curr_window && window == gdk_window_get_toplevel (curr_window)))
- SetCursor (hcursor);
- else
- {
- /* Climb up the tree and find whether our window is the
- * first ancestor that has cursor defined, and if so, set
- * new cursor.
- */
- while (curr_window && curr_window->impl &&
- !GDK_WINDOW_IMPL_WIN32 (curr_window->impl)->hcursor)
- {
- curr_window = curr_window->parent;
- if (curr_window == GDK_WINDOW (window))
- {
- SetCursor (hcursor);
- break;
- }
- }
- }
- }
-
- /* Unset the previous cursor: Need to make sure it's no longer in
- * use before we destroy it, in case we're not over our window but
- * the cursor is still set to our old one.
- */
- if (hprevcursor != NULL &&
- GetCursor () == hprevcursor)
- {
- /* Look for a suitable cursor to use instead */
- hcursor = NULL;
- parent_window = GDK_WINDOW (window)->parent;
-
- while (hcursor == NULL)
- {
- if (parent_window)
- {
- impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
- hcursor = impl->hcursor;
- parent_window = parent_window->parent;
- }
- else
- hcursor = LoadCursor (NULL, IDC_ARROW);
- }
-
- SetCursor (hcursor);
- }
}
static void
gint x,
gint y)
{
- SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
}
static GdkModifierType
GdkCursor *cursor,
guint32 time_)
{
- GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- HCURSOR hcursor;
- GdkWin32Cursor *cursor_private;
-
- cursor_private = (GdkWin32Cursor*) cursor;
-
- if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
- {
- if (!cursor)
- hcursor = NULL;
- else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)
- WIN32_API_FAILED ("CopyCursor");
-
- if (_gdk_win32_grab_cursor != NULL)
- {
- if (GetCursor () == _gdk_win32_grab_cursor)
- SetCursor (NULL);
- DestroyCursor (_gdk_win32_grab_cursor);
- }
-
- _gdk_win32_grab_cursor = hcursor;
-
- if (_gdk_win32_grab_cursor != NULL)
- SetCursor (_gdk_win32_grab_cursor);
- else if (impl->hcursor != NULL)
- SetCursor (impl->hcursor);
- else
- SetCursor (LoadCursor (NULL, IDC_ARROW));
-
- SetCapture (GDK_WINDOW_HWND (window));
- }
-
- return GDK_GRAB_SUCCESS;
+ /* No support for grabbing the slave atm */
+ return GDK_GRAB_NOT_VIEWABLE;
}
static void
gdk_device_win32_ungrab (GdkDevice *device,
guint32 time_)
{
- GdkDeviceGrabInfo *info;
- GdkDisplay *display;
-
- display = gdk_device_get_display (device);
- info = _gdk_display_get_last_device_grab (display, device);
-
- if (info)
- info->serial_end = 0;
-
- if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
- {
- if (_gdk_win32_grab_cursor != NULL)
- {
- if (GetCursor () == _gdk_win32_grab_cursor)
- SetCursor (NULL);
- DestroyCursor (_gdk_win32_grab_cursor);
- }
- _gdk_win32_grab_cursor = NULL;
-
- ReleaseCapture ();
- }
-
- _gdk_display_device_grab_update (display, device, NULL, 0);
}
static void
#include "gdkwin32.h"
#include "gdkdevice-wintab.h"
-static GQuark quark_window_input_info = 0;
-static GSList *input_windows = NULL;
-
-typedef struct
-{
- gdouble root_x;
- gdouble root_y;
- GHashTable *device_events;
-} GdkWindowInputInfo;
-
static gboolean gdk_device_wintab_get_history (GdkDevice *device,
GdkWindow *window,
guint32 start,
device_class->ungrab = gdk_device_wintab_ungrab;
device_class->window_at_position = gdk_device_wintab_window_at_position;
device_class->select_window_events = gdk_device_wintab_select_window_events;
-
- quark_window_input_info = g_quark_from_static_string ("gdk-window-input-info");
}
static void
return FALSE;
}
+static GdkModifierType
+get_current_mask (void)
+{
+ GdkModifierType mask;
+ BYTE kbd[256];
+
+ GetKeyboardState (kbd);
+ mask = 0;
+ if (kbd[VK_SHIFT] & 0x80)
+ mask |= GDK_SHIFT_MASK;
+ if (kbd[VK_CAPITAL] & 0x80)
+ mask |= GDK_LOCK_MASK;
+ if (kbd[VK_CONTROL] & 0x80)
+ mask |= GDK_CONTROL_MASK;
+ if (kbd[VK_MENU] & 0x80)
+ mask |= GDK_MOD1_MASK;
+ if (kbd[VK_LBUTTON] & 0x80)
+ mask |= GDK_BUTTON1_MASK;
+ if (kbd[VK_MBUTTON] & 0x80)
+ mask |= GDK_BUTTON2_MASK;
+ if (kbd[VK_RBUTTON] & 0x80)
+ mask |= GDK_BUTTON3_MASK;
+
+ return mask;
+}
+
static void
gdk_device_wintab_get_state (GdkDevice *device,
GdkWindow *window,
* second, the info should be fairly up to date */
if (mask)
{
- gdk_window_get_pointer (window, NULL, NULL, mask);
+ *mask = get_current_mask ();
*mask &= 0xFF; /* Mask away core pointer buttons */
*mask |= ((device_wintab->button_state << 8)
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
| GDK_BUTTON5_MASK));
}
- if (device_wintab->last_axis_data)
+ if (axes && device_wintab->last_axis_data)
_gdk_device_wintab_translate_axes (device_wintab, window, axes, NULL, NULL);
}
gint *win_y,
GdkModifierType *mask)
{
- g_warning ("query_state unimplemented for wintab devices. Expect bad things.");
+ GdkDeviceWintab *device_wintab;
+ POINT point;
+ HWND hwnd, hwndc;
+
+ device_wintab = GDK_DEVICE_WINTAB (device);
+
+ hwnd = GDK_WINDOW_HWND (window);
+ GetCursorPos (&point);
+
+ if (root_x)
+ *root_x = point.x;
+
+ if (root_y)
+ *root_y = point.y;
+
+ ScreenToClient (hwnd, &point);
+
+ if (win_x)
+ *win_x = point.x;
+
+ if (win_y)
+ *win_y = point.y;
+
+ if (window == _gdk_root)
+ {
+ if (win_x)
+ *win_x += _gdk_offset_x;
+
+ if (win_y)
+ *win_y += _gdk_offset_y;
+ }
+
+ if (child_window)
+ {
+ hwndc = ChildWindowFromPoint (hwnd, point);
+
+ if (hwndc && hwndc != hwnd)
+ *child_window = gdk_win32_handle_table_lookup (hwndc);
+ else
+ *child_window = NULL; /* Direct child unknown to gdk */
+ }
+
+ if (root_window)
+ {
+ GdkScreen *screen;
+
+ screen = gdk_window_get_screen (window);
+ *root_window = gdk_screen_get_root_window (screen);
+ }
+
+ if (mask)
+ {
+ *mask = get_current_mask ();
+ *mask &= 0xFF; /* Mask away core pointer buttons */
+ *mask |= ((device_wintab->button_state << 8)
+ & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
+ | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
+ | GDK_BUTTON5_MASK));
+
+ }
}
static GdkGrabStatus
return NULL;
}
-static void
-input_info_free (GdkWindowInputInfo *info)
-{
- g_hash_table_destroy (info->device_events);
- g_free (info);
-}
-
static void
gdk_device_wintab_select_window_events (GdkDevice *device,
GdkWindow *window,
GdkEventMask event_mask)
{
- GdkWindowInputInfo *info;
-
- info = g_object_get_qdata (G_OBJECT (window),
- quark_window_input_info);
- if (event_mask)
- {
- if (!info)
- {
- info = g_new0 (GdkWindowInputInfo, 1);
- info->device_events = g_hash_table_new (NULL, NULL);
-
- g_object_set_qdata_full (G_OBJECT (window),
- quark_window_input_info,
- info,
- (GDestroyNotify) input_info_free);
- input_windows = g_slist_prepend (input_windows, window);
- }
-
- g_hash_table_insert (info->device_events, device,
- GUINT_TO_POINTER (event_mask));
- }
- else if (info)
- {
- g_hash_table_remove (info->device_events, device);
-
- if (g_hash_table_size (info->device_events) == 0)
- {
- g_object_set_qdata (G_OBJECT (window),
- quark_window_input_info,
- NULL);
- input_windows = g_slist_remove (input_windows, window);
- }
- }
-}
-
-gboolean
-_gdk_device_wintab_wants_events (GdkWindow *window)
-{
- GdkWindowInputInfo *info;
-
- info = g_object_get_qdata (G_OBJECT (window),
- quark_window_input_info);
-
- return info != NULL;
-}
-
-GdkEventMask
-_gdk_device_wintab_get_events (GdkDeviceWintab *device,
- GdkWindow *window)
-{
- GdkWindowInputInfo *info;
-
- info = g_object_get_qdata (G_OBJECT (window),
- quark_window_input_info);
-
- if (!info)
- return 0;
-
- return GPOINTER_TO_UINT (g_hash_table_lookup (info->device_events, device));
-}
-
-gboolean
-_gdk_device_wintab_get_window_coords (GdkWindow *window,
- gdouble *root_x,
- gdouble *root_y)
-{
- GdkWindowInputInfo *info;
-
- info = g_object_get_qdata (G_OBJECT (window),
- quark_window_input_info);
-
- if (!info)
- return FALSE;
-
- *root_x = info->root_x;
- *root_y = info->root_y;
-
- return TRUE;
-}
-
-void
-_gdk_device_wintab_update_window_coords (GdkWindow *window)
-{
- GdkWindowInputInfo *info;
- gint root_x, root_y;
-
- info = g_object_get_qdata (G_OBJECT (window),
- quark_window_input_info);
-
- g_return_if_fail (info != NULL);
-
- gdk_window_get_origin (window, &root_x, &root_y);
- info->root_x = (gdouble) root_x;
- info->root_y = (gdouble) root_y;
}
void
{
GdkDevice *device;
GdkWindow *impl_window;
- gdouble root_x, root_y;
+ gint root_x, root_y;
gdouble temp_x, temp_y;
gint i;
impl_window = _gdk_window_get_impl_window (window);
temp_x = temp_y = 0;
- if (!_gdk_device_wintab_get_window_coords (impl_window, &root_x, &root_y))
- return;
+ gdk_window_get_origin (impl_window, &root_x, &root_y);
for (i = 0; i < gdk_device_get_n_axes (device); i++)
{
{
GdkDevice parent_instance;
+ gboolean sends_core;
gint *last_axis_data;
gint button_state;
GType gdk_device_wintab_get_type (void) G_GNUC_CONST;
-gboolean _gdk_device_wintab_wants_events (GdkWindow *window);
-GdkEventMask _gdk_device_wintab_get_events (GdkDeviceWintab *device,
- GdkWindow *window);
-gboolean _gdk_device_wintab_get_window_coords (GdkWindow *window,
- gdouble *root_x,
- gdouble *root_y);
-void _gdk_device_wintab_update_window_coords (GdkWindow *window);
-
void _gdk_device_wintab_translate_axes (GdkDeviceWintab *device,
GdkWindow *window,
gdouble *axes,
#include "gdkdevicemanager-win32.h"
#include "gdkdeviceprivate.h"
#include "gdkdevice-win32.h"
+#include "gdkdevice-virtual.h"
#include "gdkdevice-wintab.h"
#include "gdkdisplayprivate.h"
#include <pktdef.h>
#define DEBUG_WINTAB 1 /* Verbose debug messages enabled */
-#define PROXIMITY_OUT_DELAY 200 /* In milliseconds, see set_ignore_core */
#define TWOPI (2 * G_PI)
static GList *wintab_contexts = NULL;
static GdkWindow *wintab_window = NULL;
-static guint ignore_core_timer = 0;
extern gint _gdk_input_ignore_core;
typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
+typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
+typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
static t_WTInfoW p_WTInfoW;
static t_WTEnable p_WTEnable;
static t_WTOpenA p_WTOpenA;
+static t_WTGetA p_WTGetA;
+static t_WTSetA p_WTSetA;
static t_WTOverlap p_WTOverlap;
static t_WTPacket p_WTPacket;
static t_WTQueueSizeSet p_WTQueueSizeSet;
}
static GdkDevice *
-create_core_pointer (GdkDeviceManager *device_manager)
+create_pointer (GdkDeviceManager *device_manager,
+ GType g_type,
+ const char *name,
+ GdkDeviceType type)
{
- return g_object_new (GDK_TYPE_DEVICE_WIN32,
- "name", "Core Pointer",
- "type", GDK_DEVICE_TYPE_MASTER,
+ return g_object_new (g_type,
+ "name", name,
+ "type", type,
"input-source", GDK_SOURCE_MOUSE,
"input-mode", GDK_MODE_SCREEN,
- "has-cursor", TRUE,
+ "has-cursor", type == GDK_DEVICE_TYPE_MASTER,
"display", _gdk_display,
"device-manager", device_manager,
NULL);
}
static GdkDevice *
-create_core_keyboard (GdkDeviceManager *device_manager)
+create_keyboard (GdkDeviceManager *device_manager,
+ GType g_type,
+ const char *name,
+ GdkDeviceType type)
{
- return g_object_new (GDK_TYPE_DEVICE_WIN32,
- "name", "Core Keyboard",
- "type", GDK_DEVICE_TYPE_MASTER,
+ return g_object_new (g_type,
+ "name", name,
+ "type", type,
"input-source", GDK_SOURCE_KEYBOARD,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
return;
if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
return;
+ if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
+ return;
+ if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
+ return;
if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
return;
if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
#if DEBUG_WINTAB
GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
#endif
- lc.lcOptions |= CXO_MESSAGES;
+ lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
lc.lcStatus = 0;
lc.lcMsgBase = WT_DEFBASE;
lc.lcPktRate = 0;
lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
lc.lcOutOrgX = axis_x.axMin;
lc.lcOutOrgY = axis_y.axMin;
- lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
- lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
+ lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
+ lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
#if DEBUG_WINTAB
GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
* with a smaller queue size.
*/
GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
- for (i = 32; i >= 1; i >>= 1)
+ for (i = 128; i >= 1; i >>= 1)
{
if ((*p_WTQueueSizeSet) (*hctx, i))
{
device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
"name", device_name,
- "type", GDK_DEVICE_TYPE_SLAVE,
+ "type", GDK_DEVICE_TYPE_FLOATING,
"input-source", GDK_SOURCE_PEN,
"input-mode", GDK_MODE_SCREEN,
- "has-cursor", FALSE,
+ "has-cursor", lc.lcOptions & CXO_SYSTEM,
"display", _gdk_display,
"device-manager", device_manager,
NULL);
+ device->sends_core = lc.lcOptions & CXO_SYSTEM;
+ if (device->sends_core)
+ {
+ _gdk_device_set_associated_device (device_manager->system_pointer, GDK_DEVICE (device));
+ _gdk_device_add_slave (device_manager->core_pointer, GDK_DEVICE (device));
+ }
+
g_free (csrname_utf8);
device->hctx = *hctx;
GdkDeviceManagerWin32 *device_manager;
device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
- device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager));
- device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager));
+ device_manager->core_pointer =
+ create_pointer (GDK_DEVICE_MANAGER (device_manager),
+ GDK_TYPE_DEVICE_VIRTUAL,
+ "Virtual Core Pointer",
+ GDK_DEVICE_TYPE_MASTER);
+ device_manager->system_pointer =
+ create_pointer (GDK_DEVICE_MANAGER (device_manager),
+ GDK_TYPE_DEVICE_WIN32,
+ "System Aggregated Pointer",
+ GDK_DEVICE_TYPE_SLAVE);
+ _gdk_device_virtual_set_active (device_manager->core_pointer,
+ device_manager->system_pointer);
+ _gdk_device_set_associated_device (device_manager->system_pointer, device_manager->core_pointer);
+ _gdk_device_add_slave (device_manager->core_pointer, device_manager->system_pointer);
+
+ device_manager->core_keyboard =
+ create_keyboard (GDK_DEVICE_MANAGER (device_manager),
+ GDK_TYPE_DEVICE_VIRTUAL,
+ "Virtual Core Keyboard",
+ GDK_DEVICE_TYPE_MASTER);
+ device_manager->system_keyboard =
+ create_keyboard (GDK_DEVICE_MANAGER (device_manager),
+ GDK_TYPE_DEVICE_WIN32,
+ "System Aggregated Keyboard",
+ GDK_DEVICE_TYPE_SLAVE);
+ _gdk_device_virtual_set_active (device_manager->core_keyboard,
+ device_manager->system_keyboard);
+ _gdk_device_set_associated_device (device_manager->system_keyboard, device_manager->core_keyboard);
+ _gdk_device_add_slave (device_manager->core_keyboard, device_manager->system_keyboard);
_gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
_gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
GdkDeviceType type)
{
GdkDeviceManagerWin32 *device_manager_win32;
- GList *devices = NULL;
+ GList *devices = NULL, *l;
device_manager_win32 = (GdkDeviceManagerWin32 *) device_manager;
devices = g_list_prepend (devices, device_manager_win32->core_keyboard);
devices = g_list_prepend (devices, device_manager_win32->core_pointer);
}
- else if (type == GDK_DEVICE_TYPE_FLOATING)
- devices = g_list_copy (device_manager_win32->wintab_devices);
+ else
+ {
+ if (type == GDK_DEVICE_TYPE_SLAVE)
+ {
+ devices = g_list_prepend (devices, device_manager_win32->system_keyboard);
+ devices = g_list_prepend (devices, device_manager_win32->system_pointer);
+ }
+
+ for (l = device_manager_win32->wintab_devices; l != NULL; l = l->next)
+ {
+ GdkDevice *device = l->data;
+
+ if (gdk_device_get_device_type (device) == type)
+ devices = g_list_prepend (devices, device);
+ }
+ }
- return devices;
+ return g_list_reverse (devices);
}
static GdkDevice *
return state;
}
-static gboolean
-ignore_core_timefunc (gpointer data)
-{
- /* The delay has passed */
- _gdk_input_ignore_core = FALSE;
- ignore_core_timer = 0;
-
- return FALSE; /* remove timeout */
-}
-
-/*
- * Set or unset the _gdk_input_ignore_core variable that tells GDK
- * to ignore events for the core pointer when the tablet is in proximity
- * The unsetting is delayed slightly so that if a tablet event arrives
- * just after proximity out, it does not cause a core pointer event
- * which e.g. causes GIMP to switch tools.
- */
-static void
-set_ignore_core (gboolean ignore)
-{
- if (ignore)
- {
- _gdk_input_ignore_core = TRUE;
- /* Remove any pending clear */
- if (ignore_core_timer)
- {
- g_source_remove (ignore_core_timer);
- ignore_core_timer = 0;
- }
- }
- else if (!ignore_core_timer)
- ignore_core_timer = gdk_threads_add_timeout (PROXIMITY_OUT_DELAY,
- ignore_core_timefunc, NULL);
-}
-
static GdkDeviceWintab *
_gdk_device_manager_find_wintab_device (HCTX hctx,
UINT cursor)
MSG *msg,
GdkWindow *window)
{
+ GdkDeviceManagerWin32 *device_manager;
GdkDisplay *display;
- GdkDeviceWintab *device = NULL;
+ GdkDeviceWintab *source_device = NULL;
GdkDeviceGrabInfo *last_grab;
GdkEventMask masktest;
guint key_state;
POINT pt;
PACKET packet;
- gdouble root_x, root_y;
+ gint root_x, root_y;
gint num_axes;
gint x, y;
guint translated_buttons, button_diff, button_mask;
return FALSE;
}
+ device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display));
+
window = gdk_window_at_pointer (&x, &y);
if (window == NULL)
window = _gdk_root;
g_print ("_gdk_input_other_event: window=%p %+d%+d\n",
GDK_WINDOW_HWND (window), x, y));
- if (msg->message == WT_PACKET)
+ if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
{
if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
return FALSE;
return FALSE;
}
- if ((device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam,
- packet.pkCursor)) == NULL)
+ if ((source_device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam,
+ packet.pkCursor)) == NULL)
return FALSE;
- if (gdk_device_get_mode (GDK_DEVICE (device)) == GDK_MODE_DISABLED)
+ if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
return FALSE;
- last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (device));
+ last_grab = _gdk_display_get_last_device_grab (_gdk_display, GDK_DEVICE (source_device));
if (last_grab && last_grab->window)
{
}
num_axes = 0;
- if (device->pktdata & PK_X)
- device->last_axis_data[num_axes++] = packet.pkX;
- if (device->pktdata & PK_Y)
- device->last_axis_data[num_axes++] = packet.pkY;
- if (device->pktdata & PK_NORMAL_PRESSURE)
- device->last_axis_data[num_axes++] = packet.pkNormalPressure;
- if (device->pktdata & PK_ORIENTATION)
+ if (source_device->pktdata & PK_X)
+ source_device->last_axis_data[num_axes++] = packet.pkX;
+ if (source_device->pktdata & PK_Y)
+ source_device->last_axis_data[num_axes++] = packet.pkY;
+ if (source_device->pktdata & PK_NORMAL_PRESSURE)
+ source_device->last_axis_data[num_axes++] = packet.pkNormalPressure;
+ if (source_device->pktdata & PK_ORIENTATION)
{
- decode_tilt (device->last_axis_data + num_axes,
- device->orientation_axes, &packet);
+ decode_tilt (source_device->last_axis_data + num_axes,
+ source_device->orientation_axes, &packet);
num_axes += 2;
}
translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
- if (translated_buttons != device->button_state)
+ if (translated_buttons != source_device->button_state)
{
/* At least one button has changed state so produce a button event
* If more than one button has changed state (unlikely),
* just care about the first and act on the next the next time
* we get a packet
*/
- button_diff = translated_buttons ^ device->button_state;
+ button_diff = translated_buttons ^ source_device->button_state;
/* Gdk buttons are numbered 1.. */
event->button.button = 1;
event->any.type = GDK_BUTTON_PRESS;
masktest = GDK_BUTTON_PRESS_MASK;
}
- device->button_state ^= button_mask;
+ source_device->button_state ^= button_mask;
}
else
{
event->any.type = GDK_MOTION_NOTIFY;
masktest = GDK_POINTER_MOTION_MASK;
- if (device->button_state & (1 << 0))
+ if (source_device->button_state & (1 << 0))
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
- if (device->button_state & (1 << 1))
+ if (source_device->button_state & (1 << 1))
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
- if (device->button_state & (1 << 2))
+ if (source_device->button_state & (1 << 2))
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
}
/* Now we can check if the window wants the event, and
* propagate if necessary.
*/
- while (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0)
+ while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 &&
+ (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE &&
+ (gdk_window_get_events (window) & masktest) == 0))
{
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
- if (window->parent == GDK_WINDOW (_gdk_root))
+ if (window->parent == GDK_WINDOW (_gdk_root) ||
+ window->parent == NULL)
return FALSE;
- /* It is not good to propagate the extended events up to the parent
- * if this window wants normal (not extended) motion/button events */
- if (window->event_mask & masktest)
- {
- GDK_NOTE (EVENTS_OR_INPUT,
- g_print ("... wants ordinary event, ignoring this\n"));
- return FALSE;
- }
-
pt.x = x;
pt.y = y;
ClientToScreen (GDK_WINDOW_HWND (window), &pt);
GDK_WINDOW_HWND (window), x, y));
}
- if (gdk_window_get_device_events (window, GDK_DEVICE (device)) == 0)
- return FALSE;
-
event->any.window = window;
key_state = get_modifier_key_state ();
if (event->any.type == GDK_BUTTON_PRESS ||
event->any.type == GDK_BUTTON_RELEASE)
{
event->button.time = _gdk_win32_get_next_tick (msg->time);
- gdk_event_set_device (event, GDK_DEVICE (device));
+ if (source_device->sends_core)
+ gdk_event_set_device (event, device_manager->core_pointer);
+ gdk_event_set_source_device (event, GDK_DEVICE (source_device));
event->button.axes = g_new (gdouble, num_axes);
- _gdk_device_wintab_get_window_coords (window, &root_x, &root_y);
+ gdk_window_get_origin (window, &root_x, &root_y);
- _gdk_device_wintab_translate_axes (device,
+ _gdk_device_wintab_translate_axes (source_device,
window,
event->button.axes,
&event->button.x,
event->button.y_root = event->button.y + root_y;
event->button.state =
- key_state | ((device->button_state << 8)
+ key_state | ((source_device->button_state << 8)
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
| GDK_BUTTON5_MASK));
{
event->motion.time = _gdk_win32_get_next_tick (msg->time);
event->motion.is_hint = FALSE;
- gdk_event_set_device (event, GDK_DEVICE (device));
+ gdk_event_set_device (event, device_manager->core_pointer);
+ gdk_event_set_source_device (event, GDK_DEVICE (source_device));
event->motion.axes = g_new (gdouble, num_axes);
- _gdk_device_wintab_get_window_coords (window, &root_x, &root_y);
+ gdk_window_get_origin (window, &root_x, &root_y);
- _gdk_device_wintab_translate_axes (device,
+ _gdk_device_wintab_translate_axes (source_device,
window,
event->motion.axes,
&event->motion.x,
event->motion.y_root = event->motion.y + root_y;
event->motion.state =
- key_state | ((device->button_state << 8)
+ key_state | ((source_device->button_state << 8)
& (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
| GDK_BUTTON5_MASK));
}
return TRUE;
+ case WT_CSRCHANGE:
+ if ((source_device = _gdk_device_manager_find_wintab_device ((HCTX) msg->lParam,
+ packet.pkCursor)) == NULL)
+ return FALSE;
+
+ if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
+ return FALSE;
+
+ if (source_device->sends_core)
+ {
+ _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (source_device));
+ _gdk_input_ignore_core = TRUE;
+ }
+
+ return FALSE;
+
case WT_PROXIMITY:
if (LOWORD (msg->lParam) == 0)
{
- event->proximity.type = GDK_PROXIMITY_OUT;
- set_ignore_core (FALSE);
+ _gdk_input_ignore_core = FALSE;
+ _gdk_device_virtual_set_active (device_manager->core_pointer,
+ device_manager->system_pointer);
}
- else
- {
- event->proximity.type = GDK_PROXIMITY_IN;
- set_ignore_core (TRUE);
- }
- event->proximity.time = _gdk_win32_get_next_tick (msg->time);
- gdk_event_set_device (event, GDK_DEVICE (device));
- GDK_NOTE (EVENTS_OR_INPUT,
- g_print ("WINTAB proximity %s\n",
- (event->proximity.type == GDK_PROXIMITY_IN ?
- "in" : "out")));
- return TRUE;
+ return FALSE;
}
return FALSE;
struct _GdkDeviceManagerWin32
{
GdkDeviceManager parent_object;
+ /* Master Devices */
GdkDevice *core_pointer;
GdkDevice *core_keyboard;
+ /* Fake slave devices */
+ GdkDevice *system_pointer;
+ GdkDevice *system_keyboard;
GList *wintab_devices;
};
gboolean in)
{
GdkDevice *device;
+ GdkDevice *source_device;
GdkEvent *event;
device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard;
+ source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_keyboard;
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = window;
event->focus_change.in = in;
gdk_event_set_device (event, device);
+ gdk_event_set_source_device (event, source_device);
_gdk_win32_append_event (event);
}
{
GdkEvent *event = gdk_event_new (GDK_GRAB_BROKEN);
GdkDevice *device;
+ GdkDevice *source_device;
if (keyboard)
- device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard;
+ {
+ device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard;
+ source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_keyboard;
+ }
else
- device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer;
+ {
+ device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer;
+ source_device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->system_pointer;
+ }
event->grab_broken.window = window;
event->grab_broken.send_event = 0;
event->grab_broken.implicit = FALSE;
event->grab_broken.grab_window = grab_window;
gdk_event_set_device (event, device);
+ gdk_event_set_source_device (event, device);
_gdk_win32_append_event (event);
}
event->crossing.detail = notify_type;
event->crossing.focus = FALSE;
event->crossing.state = mask;
- gdk_event_set_device (event, _gdk_display->core_pointer);
+ gdk_event_set_device (event, device_manager->core_pointer);
+ gdk_event_set_source_device (event, device_manager->system_pointer);
_gdk_win32_append_event (event);
-
- if (type == GDK_ENTER_NOTIFY &&
- _gdk_device_wintab_wants_events (window))
- _gdk_device_wintab_update_window_coords (window);
}
static GdkWindow *
MSG *msg)
{
GdkEvent *event = gdk_event_new (type);
+ GdkDeviceManagerWin32 *device_manager;
+
+ if (_gdk_input_ignore_core)
+ return;
+
+ device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display));
event->button.window = window;
event->button.time = _gdk_win32_get_next_tick (msg->time);
event->button.axes = NULL;
event->button.state = build_pointer_event_state (msg);
event->button.button = button;
- gdk_event_set_device (event, _gdk_display->core_pointer);
+ gdk_event_set_device (event, device_manager->core_pointer);
+ gdk_event_set_source_device (event, device_manager->system_pointer);
_gdk_win32_append_event (event);
}
GdkWindow *orig_window, *new_window;
GdkDeviceManager *device_manager;
+ GdkDeviceManagerWin32 *device_manager_win32;
GdkDeviceGrabInfo *keyboard_grab = NULL;
GdkDeviceGrabInfo *pointer_grab = NULL;
}
device_manager = gdk_display_get_device_manager (_gdk_display);
+ device_manager_win32 = GDK_DEVICE_MANAGER_WIN32 (device_manager);
keyboard_grab = _gdk_display_get_last_device_grab (_gdk_display,
- GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
+ device_manager_win32->core_keyboard);
pointer_grab = _gdk_display_get_last_device_grab (_gdk_display,
- GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer);
+ device_manager_win32->core_pointer);
g_object_ref (window);
event->key.string = NULL;
event->key.length = 0;
event->key.hardware_keycode = msg->wParam;
- gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
+ gdk_event_set_device (event, device_manager_win32->core_keyboard);
+ gdk_event_set_source_device (event, device_manager_win32->system_keyboard);
if (HIWORD (msg->lParam) & KF_EXTENDED)
{
switch (msg->wParam)
/* Build a key press event */
event = gdk_event_new (GDK_KEY_PRESS);
event->key.window = window;
- gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
+ gdk_event_set_device (event, device_manager_win32->core_keyboard);
+ gdk_event_set_source_device (event, device_manager_win32->system_keyboard);
build_wm_ime_composition_event (event, msg, wbuf[i], key_state);
_gdk_win32_append_event (event);
/* Build a key release event. */
event = gdk_event_new (GDK_KEY_RELEASE);
event->key.window = window;
- gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
+ gdk_event_set_device (event, device_manager_win32->core_keyboard);
+ gdk_event_set_source_device (event, device_manager_win32->system_keyboard);
build_wm_ime_composition_event (event, msg, wbuf[i], key_state);
_gdk_win32_append_event (event);
current_root_x = msg->pt.x + _gdk_offset_x;
current_root_y = msg->pt.y + _gdk_offset_y;
- event = gdk_event_new (GDK_MOTION_NOTIFY);
- event->motion.window = window;
- event->motion.time = _gdk_win32_get_next_tick (msg->time);
- event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
- event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
- event->motion.x_root = current_root_x;
- event->motion.y_root = current_root_y;
- event->motion.axes = NULL;
- event->motion.state = build_pointer_event_state (msg);
- event->motion.is_hint = FALSE;
- gdk_event_set_device (event, _gdk_display->core_pointer);
+ if (!_gdk_input_ignore_core)
+ {
+ event = gdk_event_new (GDK_MOTION_NOTIFY);
+ event->motion.window = window;
+ event->motion.time = _gdk_win32_get_next_tick (msg->time);
+ event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
+ event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
+ event->motion.x_root = current_root_x;
+ event->motion.y_root = current_root_y;
+ event->motion.axes = NULL;
+ event->motion.state = build_pointer_event_state (msg);
+ event->motion.is_hint = FALSE;
+ gdk_event_set_device (event, device_manager_win32->core_pointer);
+ gdk_event_set_source_device (event, device_manager_win32->system_pointer);
- _gdk_win32_append_event (event);
+ _gdk_win32_append_event (event);
+ }
return_val = TRUE;
break;
event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x;
event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y;
event->scroll.state = build_pointer_event_state (msg);
- gdk_event_set_device (event, _gdk_display->core_pointer);
+ gdk_event_set_device (event, device_manager_win32->core_pointer);
+ gdk_event_set_source_device (event, device_manager_win32->system_pointer);
_gdk_win32_append_event (event);
!IsIconic (msg->hwnd) &&
!GDK_WINDOW_DESTROYED (window))
_gdk_win32_emit_configure_event (window);
-
- if (_gdk_device_wintab_wants_events (window))
- _gdk_device_wintab_update_window_coords (window);
}
if ((windowpos->flags & SWP_HIDEWINDOW) &&
_gdk_input_devices = g_list_concat (_gdk_input_devices,
g_list_copy (device_manager->wintab_devices));
- _gdk_input_wintab_init_check (device_manager);
+ _gdk_input_wintab_init_check (GDK_DEVICE_MANAGER (device_manager));
}